package com.xtayfjpk.security;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

import org.junit.Test;

public class UnsymmetricAlgorithmTest {
	private static final String DH = "DH";
	private static final String DES = "DES";
	
	//一致性
	@Test
	public void test() throws Exception {
		System.out.println("alice:产生DH对...");
		KeyPairGenerator aliceGen = KeyPairGenerator.getInstance("DH");
		KeyPair alicePair = aliceGen.generateKeyPair();
		
		//Alice生成公共密钥并发送给Bob
		byte[] alicePublicEncoded = alicePair.getPublic().getEncoded();
		//Bob接收到Alice的编码后的公钥，将其解码
		KeyFactory bobKeyFactory = KeyFactory.getInstance(DH);
		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(alicePublicEncoded);
		PublicKey alicePublicKey = bobKeyFactory.generatePublic(x509EncodedKeySpec);
		System.out.println("Bob 解码Alice公钥成功");
		
		//Bob必须使用相同的参数初始化他的DH KEY对，所以要从Alice发给他的公开密钥中读取参数
		//再用这个参数初始他的DH KEY对
		DHParameterSpec dhParameterSpec = DHPublicKey.class.cast(alicePublicKey).getParams();
		KeyPairGenerator bobGen = KeyPairGenerator.getInstance(DH);
		bobGen.initialize(dhParameterSpec);
		KeyPair bobPair = bobGen.generateKeyPair();
		System.out.println("Bob生成DH KEY对成功");
		
		
		//Bob生成本地密钥
		KeyAgreement bobKeyAgreement = KeyAgreement.getInstance(DH);
		bobKeyAgreement.init(bobPair.getPrivate());
		System.out.println("Bob: 初始化本地 key 成功");
		bobKeyAgreement.doPhase(alicePublicKey, true);
		SecretKey bobSecretKey = bobKeyAgreement.generateSecret(DES);
		System.out.println("BOB: 用 alice 的公钥定位本地 key, 生成本地 DES 密钥成功"); 
       
		
		// Bob 生成公共密钥 bobPubKeyEnc 并发送给 Alice, 
        // 比如用文件方式 ,socket....., 使其生成本地密钥
		byte[] bobPublicEncoded = bobPair.getPublic().getEncoded();
		//Bob接收到Alice的编码后的公钥，将其解码
		KeyFactory aliceKeyFactory = KeyFactory.getInstance(DH);
		X509EncodedKeySpec bobX509EncodedKeySpec = new X509EncodedKeySpec(bobPublicEncoded);
		PublicKey bobPublicKey = aliceKeyFactory.generatePublic(bobX509EncodedKeySpec);
		System.out.println("Alice 解码Bob公钥成功");
		
		//Bob生成本地密钥
		KeyAgreement aliceKeyAgreement = KeyAgreement.getInstance(DH);
		aliceKeyAgreement.init(alicePair.getPrivate());
		System.out.println("Alice: 初始化本地 key 成功");
		aliceKeyAgreement.doPhase(bobPublicKey, true);
		SecretKey aliceSecretKey = aliceKeyAgreement.generateSecret(DES);
		System.out.println("Alice: 用Bob 的公钥定位本地 key, 生成本地 DES 密钥成功"); 
		
		
		if(alicePair.getPrivate().equals(bobPair.getPrivate())) {
			System.out.println("私钥相同");
		}
		if(aliceSecretKey.equals(bobSecretKey)) {
			System.out.println("密钥相同");
		}
		if(alicePublicKey.equals(bobPublicKey)) {
			System.out.println("公钥相同");
		}
		
		
		
		
		//Bob用本地key加密
		Cipher bobCipher = Cipher.getInstance(DES);
		bobCipher.init(Cipher.ENCRYPT_MODE, bobSecretKey);
		String bobInfo = "这是Bob的机蜜信息";
		System.out.println("Bob加密前原文：" + bobInfo);
		byte[] cipherText = bobCipher.doFinal(bobInfo.getBytes());
		
		
		Cipher aliceCipher = Cipher.getInstance(DES);
		aliceCipher.init(Cipher.DECRYPT_MODE, aliceSecretKey);
		byte[] recovred = aliceCipher.doFinal(cipherText);
		System.out.println("Alice解密Bob的信息：" + new String(recovred));
		
	}
	
	
	@Test
	public void mytest() throws Exception {
		KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
		KeyPair keyPair = keyPairGenerator.generateKeyPair();
		System.out.println(keyPair.getPrivate());
		
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
		String info = "这是我的秘密";
		byte[] ciphered = cipher.doFinal(info.getBytes());
		System.out.println(ciphered.length);
		
		cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
		byte[] recovred = cipher.doFinal(ciphered);
		System.out.println(new String(recovred));
		
	}
}
